import multiprocessing
import tkinter as tk
import time
import configparser
import os
import glob
from spcparser import *
import shutil
import sys
from web import *

# 定义一个函数作为子进程的循环体
def worker(stop_event, pause_event,q):
    # 解析config.ini
    config_file = 'config.ini'
    config = configparser.ConfigParser()
    if os.path.exists(config_file):
        config.read(config_file,encoding='utf-8')
    else:
        q.put("没找到到config.ini.请准备好，并重新运行程序。 " )
        return
    
    spath,dpath,epath,ppath = getThreePaths(config,config_file)
    with open(dpath + '\\' + time.strftime("%Y-%m-%d", time.localtime()) + '.txt', 'a') as f:
        f.write('开始\n')
    # 获取 spath 目录 和它子目录下的csv文件，并放入 csv_files_set 里
    csv_files = glob.glob(os.path.join(config['PATH']['spath'], '*.csv'))
    csv_files_set=set(csv_files)
    
    while not stop_event.is_set():
        lastTime = time.time()
        if pause_event.is_set(): 
            time.sleep(1)
            continue
        
        spath,dpath,epath,ppath = getThreePaths(config,config_file)
        # 获取 spath 目录 和它子目录下的csv文件，并放入 csv_files_set 里
        csv_files = glob.glob(os.path.join(config['PATH']['spath'], '*.csv'))
        csv_files_set_new = set(csv_files)
        newfiles = csv_files_set_new - csv_files_set
        for newfile in newfiles:
            try:
                # q.put("发现新文件："+newfile)
                file_info,c  = parse_scp(newfile)
                passfmt = config.get('FMT','pass')
                rows = okRows(passfmt,c)
                if isinstance(rows,list):
                    for row in rows:
                        q.put(",".join(row)+"\n")
                
                failfmt = config.get('FMT','fail')
                rows = ngRows(failfmt,c)
                if isinstance(rows,list):
                    for row in rows:
                        q.put(",".join(row)+"\n")
                
                csv_files_set.add(newfile)
            except Exception as e:
                # q.put("出错文件："+newfile+" "+str(e))
                # 复制 newfile 到 dpath 下
                # shutil.copy(newfile,dpath)
                csv_files_set.add(newfile)
            finally:
                # q.put("文件处理结束："+newfile)
                pass
            
            # csv_filename = os.path.basename(newfile)
        
        now = time.time()
        # 如果 now-lastTime > 2秒, 就sleep 这个差值
        seconds = int(config.get('TIME','seconds'))
        if now - lastTime < seconds:
            q.put("等待"+str(seconds-(now-lastTime))+"秒")
            time.sleep(seconds-(now-lastTime))
    
    # 子进程结束前可以执行一些清理工作
    q.put("即将关闭程序")
    # 确保队列中的消息都被处理完毕后再退出
    time.sleep(0.5)


def getThreePaths(config,config_file):
    config.read(config_file,encoding='utf-8')
    #读取 path 配置中的 spath dpath epath 值
    spath = config.get('PATH', 'spath')
    dpath = config.get('PATH', 'dpath')
    epath = config.get('PATH', 'epath')
    ppath = config.get('PATH', 'ppath')
    return spath,dpath,epath,ppath



class UserAdmin(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.master.title("User Admin")
        
        # 创建一个队列用于进程间通信
        self.queue = multiprocessing.Queue()
        self.process = None
        self.webServer = None
        self.stop_event = multiprocessing.Event()
        self.pause_event = multiprocessing.Event()
        self.pause_event.set()
        self.btn_run= tk.Button(self.master, text="停止中", command=self.pause_worker)
        self.btn_run.pack()
        # 初始化文本框控件,并设置文本框有竖直滚动条
        self.text_box = tk.Text(self.master, height=15, width=50, wrap=tk.WORD)  # 设置文本自动换行
        self.scroll_bar = tk.Scrollbar(self.master, command=self.text_box.yview)  # 为滚动条关联文本框的垂直视图
        self.text_box.config(yscrollcommand=self.scroll_bar.set)  # 设置文本框调用滚动条的 set 方法来更新滚动条的位置

        # 布局控件
        self.text_box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)  # 让文本框填满可用空间
        self.scroll_bar.pack(side=tk.RIGHT, fill=tk.Y)  # 将滚动条放置在文本框的右边，并填满竖直空间

        # 启动定时任务，用于检查队列并更新文本框
        self.update_timer()

    def start_worker(self):
        if self.process is None or not self.process.is_alive():
            # 启动子进程
            self.process = multiprocessing.Process(target=worker, args=(self.stop_event, self.pause_event,self.queue))
            self.process.daemon = True
            self.process.start()
            
    def start_webServer(self):
        if self.webServer is None or not self.webServer.is_alive():
            # 启动子进程
            self.webServer = multiprocessing.Process(target=runWerServer)
            self.webServer.daemon = True
            self.webServer.start()
            

    def update_timer(self):
        # 从队列中读取内容，并更新到文本框
        while not self.queue.empty():
            content = self.queue.get(0)  # 阻塞读取
            
            # 解析config.ini
            config_file = 'config.ini'
            config = configparser.ConfigParser()
            if os.path.exists(config_file):
                config.read(config_file,encoding='utf-8')
            else:
                return
            spath,dpath,epath,ppath = getThreePaths(config,config_file)
            # 把 content 追加到 dpath 目录下 的txt文件里，文件是当前的时间
            # if content.strip().startswith("TEST:"):
            with open(dpath + '\\' + time.strftime("%Y-%m-%d", time.localtime()) + '.txt', 'a') as f:
                f.write(content.strip() + '\n')
            self.text_box.insert(tk.END, content.strip() + '\n')
            self.text_box.see('end-1c')
        # 继续定时读取队列
        self.master.after(100, self.update_timer)

    def on_closing(self):
        # 关闭窗口前的事件处理
        self.stop_event.set()  # 设置停止标志
        if self.process is not None:
            self.process.join()  # 等待子进程结束
        self.webServer.terminate() 
        self.webServer.join()
        self.master.destroy()

    def pause_worker(self):
        if self.pause_event.is_set():  # 如果已经暂停，则恢复
            self.pause_event.clear()
            #设置 开始按钮的文字为“运行中...”
            self.btn_run.config(text="运行中...")
        else:
            self.pause_event.set()
            #设置 开始按钮的文字为“停止中...”
            self.btn_run.config(text="停止中...")

if __name__ == "__main__":
    multiprocessing.freeze_support()
        
    # 这里是你的多进程代码
    app = UserAdmin(master=tk.Tk())

    # 启动子进程
    app.start_worker()
    app.start_webServer()

    # 绑定窗口关闭事件
    app.master.protocol("WM_DELETE_WINDOW", app.on_closing)
    app.mainloop()